package com.edgar.plugin.hooks;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.util.Singleton;

import com.edgar.plugin.PluginIntents;
import com.edgar.plugin.SystemClassHolder;
import com.edgar.plugin.stub.ActivityStub;
import com.edgar.plugin.utils.FieldUtils;
import com.edgar.plugin.utils.MethodUtils;
import com.edgar.plugin.utils.ClassUtils;

import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * Created by Edgar on 2018/2/8.
 */
public class ActivityManagerHook extends Hook{
    public ActivityManagerHook(Context context){
        super(context);
    }

    @Override
    protected void onInstall(Context context) {
        Class<?> activityManagerNative = ClassUtils.loadClass("android.app.ActivityManagerNative");
        MethodUtils.invokeStaticMethod(activityManagerNative,"getDefault",null);
        Object object = FieldUtils.readStaticField(activityManagerNative,"gDefault");
        Object oldObject = FieldUtils.readField(Singleton.class,object,"mInstance");
        setOldObject(oldObject);
        Class<?> iActivityManagerClass = SystemClassHolder.activityManagerClass();
        FieldUtils.writeField(Singleton.class,object,"mInstance", Proxy.newProxyInstance(iActivityManagerClass.getClassLoader(),new Class[]{iActivityManagerClass},this));
    }

    @Override
    protected void onInitHookMethodHandle(Map<String, HookMethodHandle> hookMethodHandles) {
        super.onInitHookMethodHandle(hookMethodHandles);
        hookMethodHandles.put("startActivity",new startActivity());
    }

    private class startActivity extends HookMethodHandle{
        @Override
        protected boolean onReplaceParameter(Object[] args) throws RemoteException {
            Intent originIntent = (Intent) args[2];
            if (getContext().getPackageName().equals(originIntent.getComponent().getPackageName())){
                return false;
            }
            Intent stubIntent = new Intent();
            stubIntent.setComponent(new ComponentName(getContext(),ActivityStub.class));
            stubIntent.putExtra(PluginIntents.EXTRA_TARGET_INTENT,originIntent);
            args[2] = stubIntent;
            return true;
        }
    }
}